use crate::db::dao::candidate_path::{CandidatePathDao, DefaultCandidatePathDao};
use crate::db::dao::candidate_path_segment_list::{
    CandidatePathSegmentListDao, DefaultCandidatePathSegmentListDao,
};
use crate::db::dao::endpoint_srv6_config::{DefaultEndpointSrv6ConfigDao, EndpointSrv6ConfigDao};
use crate::db::dao::segment::{DefaultSegmentDao, SegmentDao};
use crate::db::dao::segment_list::{DefaultSegmentListDao, SegmentListDao};
use crate::db::dao::te_policy_group::{DefaultTePolicyGroupDao, TePolicyGroupDao};
use crate::db::dao::traffic_steering_rule::{
    DefaultTrafficSteeringRuleDao, TrafficSteeringRuleDao,
};
use crate::db::dao::{
    endpoint::{DefaultEndpointDao, EndpointDao},
    endpoint_peer::{DefaultEndpointPeerDao, EndpointPeerDao},
    endpoint_peer_wireguard_config::{
        DefaultEndpointPeerWireguardConfigDao, EndpointPeerWireguardConfigDao,
    },
    endpoint_wireguard_config::{DefaultEndpointWireguardConfigDao, EndpointWireguardConfigDao},
    user::{DefaultUserDao, UserDao},
    user_group::{DefaultUserGroupDao, UserGroupDao},
    user_group_user::{DefaultUserGroupUserDao, UserGroupUserDao},
};
use sea_orm::DatabaseConnection;
use std::sync::Arc;
use crate::db::dao::network_acl::{DefaultNetworkAclDao, NetworkAclDao};
use crate::db::dao::network_acl_rule::{DefaultNetworkAclRuleDao, NetworkAclRuleDao};

pub struct DaoSet {
    pub user: Arc<dyn UserDao>,
    pub user_group: Arc<dyn UserGroupDao>,
    pub user_group_user: Arc<dyn UserGroupUserDao>,
    pub endpoint: Arc<dyn EndpointDao>,
    pub endpoint_srv6_config: Arc<dyn EndpointSrv6ConfigDao>,
    pub endpoint_wireguard_config: Arc<dyn EndpointWireguardConfigDao>,
    pub endpoint_peer: Arc<dyn EndpointPeerDao>,
    pub endpoint_peer_wireguard_config: Arc<dyn EndpointPeerWireguardConfigDao>,
    pub te_policy_group: Arc<dyn TePolicyGroupDao>,
    pub candidate_path: Arc<dyn CandidatePathDao>,
    pub candidate_path_segment_list: Arc<dyn CandidatePathSegmentListDao>,
    pub segment: Arc<dyn SegmentDao>,
    pub segment_list: Arc<dyn SegmentListDao>,
    pub network_acl: Arc<dyn NetworkAclDao>,
    pub network_acl_rule: Arc<dyn NetworkAclRuleDao>,
    pub traffic_steering_rule: Arc<dyn TrafficSteeringRuleDao>,
}

impl DaoSet {
    pub fn new(db: DatabaseConnection) -> Self {
        Self {
            user: Arc::new(DefaultUserDao::new(db.clone())),
            user_group: Arc::new(DefaultUserGroupDao::new(db.clone())),
            user_group_user: Arc::new(DefaultUserGroupUserDao::new(db.clone())),
            endpoint: Arc::new(DefaultEndpointDao::new(db.clone())),
            endpoint_srv6_config: Arc::new(DefaultEndpointSrv6ConfigDao::new(db.clone())),
            endpoint_wireguard_config: Arc::new(DefaultEndpointWireguardConfigDao::new(db.clone())),
            endpoint_peer: Arc::new(DefaultEndpointPeerDao::new(db.clone())),
            endpoint_peer_wireguard_config: Arc::new(DefaultEndpointPeerWireguardConfigDao::new(
                db.clone(),
            )),
            te_policy_group: Arc::new(DefaultTePolicyGroupDao::new(db.clone())),
            candidate_path: Arc::new(DefaultCandidatePathDao::new(db.clone())),
            candidate_path_segment_list: Arc::new(DefaultCandidatePathSegmentListDao::new(
                db.clone(),
            )),
            segment: Arc::new(DefaultSegmentDao::new(db.clone())),
            segment_list: Arc::new(DefaultSegmentListDao::new(db.clone())),
            network_acl: Arc::new(DefaultNetworkAclDao::new(db.clone())),
            network_acl_rule: Arc::new(DefaultNetworkAclRuleDao::new(db.clone())),
            traffic_steering_rule: Arc::new(DefaultTrafficSteeringRuleDao::new(db)),
        }
    }
}
